from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import pyqtSignal, Qt,  QDir
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QApplication, QLabel
from matplotlib.pyplot import rcParams, figure, legend, plot
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from numpy import pi, sin, cos, linspace, meshgrid, around, multiply, tan
from Calculate_HighAzim2angle import Solar_angle

class DoP_Model(QWidget):

    DoP_Model_success_signal = pyqtSignal()

    def __init__(self, time_zone, lat, long, year, month, day, hours, minutes, seconds, Declination=None):
        super(DoP_Model, self).__init__()
        self.setWindowTitle("DoP Model")
        self.setWindowModality(Qt.WindowModal)
        self.Declination_agle = Declination
        self.setMaximumSize(600, 600)
        self.setStyleSheet('background-color: #ffffff;')
        self.time_zone = time_zone
        self.lat = lat
        self.long = long
        self.year = year
        self.month = month
        self.day = day
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds

        self.PsLine = None
        self.xx = None

        currentPath = QDir.currentPath()
        currentPath = currentPath.replace('/', '\\')
        rcParams['font.size'] = 10
        rcParams['axes.unicode_minus'] = False
        rcParams['font.sans-serif'] = ['SimHei', 'Times New Roman']

        self.VBoxLayout = QVBoxLayout()
        self.Image_HLayout = QHBoxLayout()
        path = currentPath + '\\cut_NESW.jpg'
        image = QPixmap(path)
        self.image_label = QLabel()
        self.image_label.setPixmap(image)
        self.image_label.setFixedHeight(110)
        self.image_label.setFixedWidth(110)
        self.Image_HLayout.addWidget(self.image_label)

        self.H2A_VLayout = QVBoxLayout()
        self.High_HLayout = QHBoxLayout()
        self.High_angle = QLabel("高度角:")
        self.High_angle.setFixedHeight(35)
        self.High_angle.setFixedWidth(60)
        self.High_angle.setAlignment(Qt.AlignCenter)
        self.High_angle.setStyleSheet("""QLabel {color:'black';
                                                font-size:10pt;
                                                font-family:"Times New Roman" , "Microsoft YaHei";}""")
        self.High_angle_view = QLabel()
        self.High_angle_view.setFixedHeight(35)
        self.High_angle_view.setFixedWidth(100)
        self.High_angle_view.setStyleSheet("""QLabel {
                                                    color:'black';
                                                    font-size:10pt;
                                                    font-family:"Times New Roman" , "Microsoft YaHei";}""")

        self.High_HLayout.addWidget(self.High_angle)
        self.High_HLayout.addWidget(self.High_angle_view)

        self.Azim_HLayout = QHBoxLayout()
        self.Azim_angle = QLabel("方位角:")
        self.Azim_angle.setFixedHeight(35)
        self.Azim_angle.setFixedWidth(60)
        self.Azim_angle.setStyleSheet("""QLabel {
                                                color:'black';
                                                font-size:10pt;
                                                font-family:"Times New Roman" , "Microsoft YaHei";}""")

        self.Azim_angle_view = QLabel()
        self.Azim_angle_view.setFixedHeight(35)
        self.Azim_angle_view.setFixedWidth(100)
        self.Azim_angle_view.setStyleSheet("""QLabel {
                                                    color:'black';
                                                    font-size:10pt;
                                                    font-family:"Times New Roman" , "Microsoft YaHei";}""")

        self.Azim_HLayout.addWidget(self.Azim_angle)
        self.Azim_HLayout.addWidget(self.Azim_angle_view)

        self.H2A_VLayout.addLayout(self.High_HLayout)
        self.H2A_VLayout.addLayout(self.Azim_HLayout)
        self.Image_HLayout.addLayout(self.H2A_VLayout)
        self.VBoxLayout.addLayout(self.Image_HLayout)

        self.HBoxLayout = QHBoxLayout()
        self.fig1 = figure(figsize=(3, 3.5))
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFixedHeight(300)
        self.canvas1.setFixedWidth(350)

        self.HBoxLayout.addWidget(self.canvas1)
        self.VBoxLayout.addLayout(self.HBoxLayout)

        self.setLayout(self.VBoxLayout)
        
        self.setup_signal()

    def setup_signal(self):
        Solar_Angle = Solar_angle(time_zone=self.time_zone, year=self.year, month=self.month, day=self.day,
                                hours=self.hours, minutes=self.minutes, seconds=self.seconds,
                                long=self.long, lat=self.lat,
                                Declination=self.Declination_agle)
        _, _, h_s, p_s = Solar_Angle.Calcu()

        str_high_angle = format(h_s, '.6f')
        self.High_angle_view.setText(str(str_high_angle))

        str_azim_angle = format(p_s, '.6f')
        self.Azim_angle_view.setText(str(str_azim_angle))

        T_s = 90 - h_s

        theta = linspace(0, 180, 210)
        theta = theta.round(1)
        phi = linspace(0, 360, 210)
        phi = phi.round(1)
        [T, P] = meshgrid(theta, phi)
        x = sin(T * pi / 180) * sin(P * pi / 180)
        x = around(2 * x, 2)
        y = sin(T * pi / 180) * cos(P * pi / 180)
        y = around(2 * y, 2)
        z = cos(T * pi / 180)
        z = around(2 * z, 2)

        k3 = sin(T_s * pi / 180) * sin(T * pi / 180) * \
             cos((p_s - P) * pi / 180) \
             + cos(T * pi / 180) * cos(T_s * pi / 180)

        DoP = (1 - multiply(k3, k3)) / (1 + multiply(k3, k3))

        PsAngle = 1 / tan(p_s * pi / 180)

        r = 2
        if 0 < p_s <= 90:
            k = p_s
            x_line = r * sin(k * pi / 180)
            self.xx = linspace(-x_line, x_line, 21)
            self.PsLine = PsAngle * self.xx
        elif 90 < p_s < 180:
            k = 180 - p_s
            x_line = r * sin(k * pi / 180)
            self.xx = linspace(-x_line, x_line, 21)
            self.PsLine = PsAngle * self.xx
        elif 180 < p_s < 270:
            k = 270 - p_s
            k = 90 - k
            x_line = r * sin(k * pi / 180)
            self.xx = linspace(-x_line, x_line, 21)
            self.PsLine = PsAngle * self.xx
        elif 270 < p_s < 360:
            k = 360 - p_s
            x_line = r * sin(k * pi / 180)
            self.xx = linspace(-x_line, x_line, 21)
            self.PsLine = PsAngle * self.xx
        elif p_s == 270:
            self.xx = linspace(-r, r, 21)
            self.PsLine = linspace(0, 0, 21)
        elif p_s == 0 or p_s == 180 or p_s == 360:
            self.xx = linspace(0, 0, 21)
            self.PsLine = linspace(-r, r, 21)

        ax1 = Axes3D(self.fig1, auto_add_to_figure=False)
        ax1.view_init(azim=-90, elev=90)
        self.fig1.add_axes(ax1)
        ax1.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
        ax1.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
        ax1.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))

        ax1.w_xaxis.line.set_color((1.0, 1.0, 1.0, 1.0))
        ax1.w_yaxis.line.set_color((1.0, 1.0, 1.0, 1.0))
        ax1.w_zaxis.line.set_color((1.0, 1.0, 1.0, 1.0))

        ax1.set_xlabel("X:W-E")
        ax1.set_ylabel("Y:S-N")
        ax1.set_zlabel("Z")
        rcParams['font.size'] = 10
        rcParams['axes.unicode_minus'] = False
        rcParams['font.sans-serif'] = ['SimHei', 'Times New Roman']

        ax1.plot_surface(x, y, z, color='w', rstride=1, cstride=1, shade=False, zorder=2, alpha=0.2)
        u = sin(phi * pi / 180)
        v = cos(phi * pi / 180)
        ax1.plot(2.1 * u, 2.1 * v, 0, color='black', zorder=3, alpha=1.0)
        around_dop = around(DoP, 2)
        size = 6
        for i in range(x.shape[0]):
            for j in range(x.shape[1]):
                if around_dop[i, j] == 0.0:
                    if 0 < p_s <= 90:
                        if x[i, j] >= 0 and y[i, j] >= 0 :
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                    elif 90 < p_s < 180:
                        if x[i, j] >= 0 and y[i, j] <= 0:
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                    elif p_s == 0 or p_s == 360:
                        if y[i, j] > 0:
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                    elif p_s == 180:
                        if y[i, j] < 0:
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                    elif 180 < p_s <= 270:
                        if x[i, j] <= 0 or y[i, j] <= 0 :
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                    elif 270 < p_s < 360:
                        if x[i, j] <= 0 and y[i, j] >= 0 :
                            type0_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='black', s=12)
                elif around_dop[i, j] == 0.1:
                    type0_1 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='darkblue', s=size)
                elif around_dop[i, j] == 0.2:
                    type0_2 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='blue', s=size)
                elif around_dop[i, j] == 0.3:
                    type0_3 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='cornflowerblue', s=size)
                elif around_dop[i, j] == 0.4:
                    type0_4 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='darkturquoise', s=size)
                elif around_dop[i, j] == 0.5:
                    type0_5 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='aqua', s=size)
                elif around_dop[i, j] == 0.6:
                    type0_6 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='cyan', s=size)
                elif around_dop[i, j] == 0.7:
                    type0_7 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='rosybrown', s=size)
                elif around_dop[i, j] == 0.8:
                    type0_8 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='lightcoral', s=size)
                elif around_dop[i, j] == 0.9:
                    type0_9 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='red', s=size)
                elif around_dop[i, j] == 1.0:
                    type1_0 = ax1.scatter(xs=x[i, j], ys=y[i, j], zs=z[i, j], c='darkred', s=size)

        legend([type0_0, type0_1, type0_2, type0_3, type0_4, type0_5, type0_6, type0_7, type0_8, type0_9, type1_0],
                   ["Sun", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0"],
                   loc='right', bbox_to_anchor=(1.1, 0.5), frameon=False,
                   prop={'family': 'Times New Roman', 'size': 10})
        plot(self.xx, self.PsLine, '-k', zorder=3)
        ax1.grid(False)
        ax1.axis('off')
        self.canvas1.draw()


if __name__ == '__main__':
    from sys import argv, exit
    app = QApplication(argv)
    MainWindow = DoP_Model(8, 39.9, 116.38333, 2022, 7, 28, 10, 24, 10)
    MainWindow.show()
    exit(app.exec_())

